/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tcc.ejb.controleProjeto.controle;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import tcc.ejb.controleProjeto.controle.exceptions.NonexistentEntityException;
import tcc.ejb.controleProjeto.controle.exceptions.PreexistingEntityException;
import tcc.ejb.controleProjeto.entidade.Artefato;
import tcc.ejb.controleProjeto.entidade.TipoArtefato;
import tcc.ejb.controleProjeto.entidade.Release;
import tcc.ejb.controleProjeto.entidade.Tarefa;
import java.util.ArrayList;
import java.util.List;
import tcc.ejb.controleProjeto.entidade.ItemArtefato;

/**
 *
 * @author Maciel
 */
public class ArtefatoJpaController {

    public ArtefatoJpaController() {
        emf = Persistence.createEntityManagerFactory("WebApplication4PU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Artefato artefato) throws PreexistingEntityException, Exception {
        if (artefato.getTarefaList() == null) {
            artefato.setTarefaList(new ArrayList<Tarefa>());
        }
        if (artefato.getItemArtefatoList() == null) {
            artefato.setItemArtefatoList(new ArrayList<ItemArtefato>());
        }
        if (artefato.getTarefaList1() == null) {
            artefato.setTarefaList1(new ArrayList<Tarefa>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoArtefato tipoArtefato = artefato.getTipoArtefato();
            if (tipoArtefato != null) {
                tipoArtefato = em.getReference(tipoArtefato.getClass(), tipoArtefato.getId());
                artefato.setTipoArtefato(tipoArtefato);
            }
            Release release = artefato.getRelease();
            if (release != null) {
                release = em.getReference(release.getClass(), release.getId());
                artefato.setRelease(release);
            }
            List<Tarefa> attachedTarefaList = new ArrayList<Tarefa>();
            for (Tarefa tarefaListTarefaToAttach : artefato.getTarefaList()) {
                tarefaListTarefaToAttach = em.getReference(tarefaListTarefaToAttach.getClass(), tarefaListTarefaToAttach.getId());
                attachedTarefaList.add(tarefaListTarefaToAttach);
            }
            artefato.setTarefaList(attachedTarefaList);
            List<ItemArtefato> attachedItemArtefatoList = new ArrayList<ItemArtefato>();
            for (ItemArtefato itemArtefatoListItemArtefatoToAttach : artefato.getItemArtefatoList()) {
                itemArtefatoListItemArtefatoToAttach = em.getReference(itemArtefatoListItemArtefatoToAttach.getClass(), itemArtefatoListItemArtefatoToAttach.getId());
                attachedItemArtefatoList.add(itemArtefatoListItemArtefatoToAttach);
            }
            artefato.setItemArtefatoList(attachedItemArtefatoList);
            List<Tarefa> attachedTarefaList1 = new ArrayList<Tarefa>();
            for (Tarefa tarefaList1TarefaToAttach : artefato.getTarefaList1()) {
                tarefaList1TarefaToAttach = em.getReference(tarefaList1TarefaToAttach.getClass(), tarefaList1TarefaToAttach.getId());
                attachedTarefaList1.add(tarefaList1TarefaToAttach);
            }
            artefato.setTarefaList1(attachedTarefaList1);
            em.persist(artefato);
            if (tipoArtefato != null) {
                tipoArtefato.getArtefatoList().add(artefato);
                tipoArtefato = em.merge(tipoArtefato);
            }
            if (release != null) {
                release.getArtefatoList().add(artefato);
                release = em.merge(release);
            }
            for (Tarefa tarefaListTarefa : artefato.getTarefaList()) {
                tarefaListTarefa.getArtefatoList().add(artefato);
                tarefaListTarefa = em.merge(tarefaListTarefa);
            }
            for (ItemArtefato itemArtefatoListItemArtefato : artefato.getItemArtefatoList()) {
                itemArtefatoListItemArtefato.getArtefatoList().add(artefato);
                itemArtefatoListItemArtefato = em.merge(itemArtefatoListItemArtefato);
            }
            for (Tarefa tarefaList1Tarefa : artefato.getTarefaList1()) {
                tarefaList1Tarefa.getArtefatoList().add(artefato);
                tarefaList1Tarefa = em.merge(tarefaList1Tarefa);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findArtefato(artefato.getId()) != null) {
                throw new PreexistingEntityException("Artefato " + artefato + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Artefato artefato) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Artefato persistentArtefato = em.find(Artefato.class, artefato.getId());
            TipoArtefato tipoArtefatoOld = persistentArtefato.getTipoArtefato();
            TipoArtefato tipoArtefatoNew = artefato.getTipoArtefato();
            Release releaseOld = persistentArtefato.getRelease();
            Release releaseNew = artefato.getRelease();
            List<Tarefa> tarefaListOld = persistentArtefato.getTarefaList();
            List<Tarefa> tarefaListNew = artefato.getTarefaList();
            List<ItemArtefato> itemArtefatoListOld = persistentArtefato.getItemArtefatoList();
            List<ItemArtefato> itemArtefatoListNew = artefato.getItemArtefatoList();
            List<Tarefa> tarefaList1Old = persistentArtefato.getTarefaList1();
            List<Tarefa> tarefaList1New = artefato.getTarefaList1();
            if (tipoArtefatoNew != null) {
                tipoArtefatoNew = em.getReference(tipoArtefatoNew.getClass(), tipoArtefatoNew.getId());
                artefato.setTipoArtefato(tipoArtefatoNew);
            }
            if (releaseNew != null) {
                releaseNew = em.getReference(releaseNew.getClass(), releaseNew.getId());
                artefato.setRelease(releaseNew);
            }
            List<Tarefa> attachedTarefaListNew = new ArrayList<Tarefa>();
            for (Tarefa tarefaListNewTarefaToAttach : tarefaListNew) {
                tarefaListNewTarefaToAttach = em.getReference(tarefaListNewTarefaToAttach.getClass(), tarefaListNewTarefaToAttach.getId());
                attachedTarefaListNew.add(tarefaListNewTarefaToAttach);
            }
            tarefaListNew = attachedTarefaListNew;
            artefato.setTarefaList(tarefaListNew);
            List<ItemArtefato> attachedItemArtefatoListNew = new ArrayList<ItemArtefato>();
            for (ItemArtefato itemArtefatoListNewItemArtefatoToAttach : itemArtefatoListNew) {
                itemArtefatoListNewItemArtefatoToAttach = em.getReference(itemArtefatoListNewItemArtefatoToAttach.getClass(), itemArtefatoListNewItemArtefatoToAttach.getId());
                attachedItemArtefatoListNew.add(itemArtefatoListNewItemArtefatoToAttach);
            }
            itemArtefatoListNew = attachedItemArtefatoListNew;
            artefato.setItemArtefatoList(itemArtefatoListNew);
            List<Tarefa> attachedTarefaList1New = new ArrayList<Tarefa>();
            for (Tarefa tarefaList1NewTarefaToAttach : tarefaList1New) {
                tarefaList1NewTarefaToAttach = em.getReference(tarefaList1NewTarefaToAttach.getClass(), tarefaList1NewTarefaToAttach.getId());
                attachedTarefaList1New.add(tarefaList1NewTarefaToAttach);
            }
            tarefaList1New = attachedTarefaList1New;
            artefato.setTarefaList1(tarefaList1New);
            artefato = em.merge(artefato);
            if (tipoArtefatoOld != null && !tipoArtefatoOld.equals(tipoArtefatoNew)) {
                tipoArtefatoOld.getArtefatoList().remove(artefato);
                tipoArtefatoOld = em.merge(tipoArtefatoOld);
            }
            if (tipoArtefatoNew != null && !tipoArtefatoNew.equals(tipoArtefatoOld)) {
                tipoArtefatoNew.getArtefatoList().add(artefato);
                tipoArtefatoNew = em.merge(tipoArtefatoNew);
            }
            if (releaseOld != null && !releaseOld.equals(releaseNew)) {
                releaseOld.getArtefatoList().remove(artefato);
                releaseOld = em.merge(releaseOld);
            }
            if (releaseNew != null && !releaseNew.equals(releaseOld)) {
                releaseNew.getArtefatoList().add(artefato);
                releaseNew = em.merge(releaseNew);
            }
            for (Tarefa tarefaListOldTarefa : tarefaListOld) {
                if (!tarefaListNew.contains(tarefaListOldTarefa)) {
                    tarefaListOldTarefa.getArtefatoList().remove(artefato);
                    tarefaListOldTarefa = em.merge(tarefaListOldTarefa);
                }
            }
            for (Tarefa tarefaListNewTarefa : tarefaListNew) {
                if (!tarefaListOld.contains(tarefaListNewTarefa)) {
                    tarefaListNewTarefa.getArtefatoList().add(artefato);
                    tarefaListNewTarefa = em.merge(tarefaListNewTarefa);
                }
            }
            for (ItemArtefato itemArtefatoListOldItemArtefato : itemArtefatoListOld) {
                if (!itemArtefatoListNew.contains(itemArtefatoListOldItemArtefato)) {
                    itemArtefatoListOldItemArtefato.getArtefatoList().remove(artefato);
                    itemArtefatoListOldItemArtefato = em.merge(itemArtefatoListOldItemArtefato);
                }
            }
            for (ItemArtefato itemArtefatoListNewItemArtefato : itemArtefatoListNew) {
                if (!itemArtefatoListOld.contains(itemArtefatoListNewItemArtefato)) {
                    itemArtefatoListNewItemArtefato.getArtefatoList().add(artefato);
                    itemArtefatoListNewItemArtefato = em.merge(itemArtefatoListNewItemArtefato);
                }
            }
            for (Tarefa tarefaList1OldTarefa : tarefaList1Old) {
                if (!tarefaList1New.contains(tarefaList1OldTarefa)) {
                    tarefaList1OldTarefa.getArtefatoList().remove(artefato);
                    tarefaList1OldTarefa = em.merge(tarefaList1OldTarefa);
                }
            }
            for (Tarefa tarefaList1NewTarefa : tarefaList1New) {
                if (!tarefaList1Old.contains(tarefaList1NewTarefa)) {
                    tarefaList1NewTarefa.getArtefatoList().add(artefato);
                    tarefaList1NewTarefa = em.merge(tarefaList1NewTarefa);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = artefato.getId();
                if (findArtefato(id) == null) {
                    throw new NonexistentEntityException("The artefato with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Artefato artefato;
            try {
                artefato = em.getReference(Artefato.class, id);
                artefato.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The artefato with id " + id + " no longer exists.", enfe);
            }
            TipoArtefato tipoArtefato = artefato.getTipoArtefato();
            if (tipoArtefato != null) {
                tipoArtefato.getArtefatoList().remove(artefato);
                tipoArtefato = em.merge(tipoArtefato);
            }
            Release release = artefato.getRelease();
            if (release != null) {
                release.getArtefatoList().remove(artefato);
                release = em.merge(release);
            }
            List<Tarefa> tarefaList = artefato.getTarefaList();
            for (Tarefa tarefaListTarefa : tarefaList) {
                tarefaListTarefa.getArtefatoList().remove(artefato);
                tarefaListTarefa = em.merge(tarefaListTarefa);
            }
            List<ItemArtefato> itemArtefatoList = artefato.getItemArtefatoList();
            for (ItemArtefato itemArtefatoListItemArtefato : itemArtefatoList) {
                itemArtefatoListItemArtefato.getArtefatoList().remove(artefato);
                itemArtefatoListItemArtefato = em.merge(itemArtefatoListItemArtefato);
            }
            List<Tarefa> tarefaList1 = artefato.getTarefaList1();
            for (Tarefa tarefaList1Tarefa : tarefaList1) {
                tarefaList1Tarefa.getArtefatoList().remove(artefato);
                tarefaList1Tarefa = em.merge(tarefaList1Tarefa);
            }
            em.remove(artefato);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Artefato> findArtefatoEntities() {
        return findArtefatoEntities(true, -1, -1);
    }

    public List<Artefato> findArtefatoEntities(int maxResults, int firstResult) {
        return findArtefatoEntities(false, maxResults, firstResult);
    }

    private List<Artefato> findArtefatoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Artefato.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Artefato findArtefato(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Artefato.class, id);
        } finally {
            em.close();
        }
    }

    public int getArtefatoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Artefato> rt = cq.from(Artefato.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
